package com.sky.controller.user;

import com.alibaba.druid.support.json.JSONUtils;
import com.sky.constant.MessageConstant;
import com.sky.constant.PayMethod;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.OrderService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description OrderController
 * @Author zhuzi
 * @Date 2023/10/05
 */
@RequestMapping("/user/order")
@RequiredArgsConstructor
@RestController("userOrderController")
@Slf4j
public class OrderController {

    private final OrderService orderService;

    /**
     * 提交订单
     *
     * @param ordersSubmitDTO OrdersSubmitDTO
     * @return Result
     */
    @PostMapping("/submit")
    public Result<OrderSubmitVO> submitOrder(@RequestBody OrdersSubmitDTO ordersSubmitDTO) {
        log.info("Get OrdersSubmitDTO: {}", ordersSubmitDTO);
        // 这里前端应该传入的是默认的地址，而不是上一次下单的地址
        return Result.success(orderService.submitOrder(ordersSubmitDTO));
    }

    /**
     * 支付
     *
     * @param ordersPaymentDTO OrdersPaymentDTO
     * @return Result
     */
    @PutMapping("/payment")
    public Result<OrderPaymentVO> Payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) {
        log.info("Get OrdersPaymentDTO: {}", ordersPaymentDTO);
        if (PayMethod.WECHAT.equals(ordersPaymentDTO.getPayMethod())) {
            return Result.success(orderService.wechatPayment(ordersPaymentDTO.getOrderNumber()));
        }
        if (PayMethod.ALIPAY.equals(ordersPaymentDTO.getPayMethod())) {
            return Result.success(orderService.alipayPayment(ordersPaymentDTO.getOrderNumber()));
        }
        return Result.error(MessageConstant.INVALID_PAYMENT_METHOD);
    }

    /**
     * 用户支付完成后，微信会把相关支付结果和用户信息发送给商户，商户需要接收处理该消息，并返回应答。
     * 支付结果通知是以POST 方法访问商户设置的通知URL，通知的数据以JSON 格式通过请求主体（BODY）传输。通知的数据包括了加密的支付结果详情。
     *
     * @param request  HttpServletRequest
     * @param response HttpServletResponse
     */
    @PostMapping("/notifyUrl")
    public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 从request获取请求体
        BufferedReader reader = request.getReader();
        StringBuilder result = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            if (result.length() > 0) {
                result.append("\n");
            }
            result.append(line);
        }

        // 处理微信支付完成的响应结果
        orderService.wechatPost(result.toString());

        // 返回响应
        response.setStatus(HttpStatus.OK.value());
        response.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
        Map<String, String> res = new HashMap<>();
        res.put("code", "SUCCESS");
        res.put("message", "成功");
        response.getOutputStream().write(JSONUtils.toJSONString(res).getBytes(StandardCharsets.UTF_8));
        response.flushBuffer(); // todo: 为什么要刷新流?
    }

    /**
     * 仅供apifox测试使用的支付接口
     *
     * @param orderNumber String
     * @return Result<?>
     */
    @RequestMapping("/apifoxPay")
    public Result<?> apifoxPay(String orderNumber) {
        log.info("Get orderNumber: {}", orderNumber);
        orderService.apifoxPay(orderNumber);
        return Result.success();
    }

    /**
     * 获取历史订单
     *
     * @param ordersPageQueryDTO OrdersPageQueryDTO
     * @return Result
     */
    @GetMapping("/historyOrders")
    public Result<PageResult> historyOrders(OrdersPageQueryDTO ordersPageQueryDTO) {
        log.info("Get OrdersPageQueryDTO: {}", ordersPageQueryDTO);
        return Result.success(orderService.historyOrders(ordersPageQueryDTO));
    }

    /**
     * 查询订单详情
     *
     * @param id Long
     * @return Result
     */
    @GetMapping("/orderDetail/{id}")
    public Result<OrderVO> getOrderDetails(@PathVariable Long id) {
        log.info("Get orderId: {}", id);
        return Result.success(orderService.getOrderDetails(id));
    }

    /**
     * 取消订单
     *
     * @param id Long
     * @return Result<?>
     */
    @PutMapping("/cancel/{id}")
    public Result<?> cancelOrder(@PathVariable Long id) {
        log.info("Get orderId: {}", id);
        orderService.userCancelOrder(id);
        return Result.success();
    }

    /**
     * 再来一单
     *
     * @param id Long
     * @return Result<?>
     */
    @PostMapping("/repetition/{id}")
    public Result<?> repetitionOrder(@PathVariable Long id) {
        log.info("Get orderId: {}", id);
        orderService.repetitionOrder(id);
        return Result.success();
    }

    /**
     * 用户催单
     *
     * @param id Long
     * @return Result<?>
     */
    @GetMapping("/reminder/{id}")
    public Result<?> reminderOrder(@PathVariable Long id) {
        log.info("Get id: {}", id);
        orderService.reminderOrder(id);
        return Result.success();
    }

}
